package com.simba.server.components;

import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

import com.simba.common.log.LogUtil;
import org.apache.log4j.Logger;
import com.simba.server.components.data.SortInfo;

public class SortInfoManager
{
	private static class SortManagerHolder
	{
		private static final SortInfoManager INSTANCE = new SortInfoManager();
	}

	protected static final Logger logger = Logger.getLogger(SortInfoManager.class);

	public static SortInfoManager getInstance()
	{
		return SortManagerHolder.INSTANCE;
	}

	private final ConcurrentHashMap<String, SortInfo> sortInfoList = new ConcurrentHashMap<>();

	private SortInfoManager()
	{
	}

	public void addSortInfo(SortInfo sortInfo)
	{
		if (sortInfo != null)
		{
			this.sortInfoList.put(sortInfo.getPlcId(), sortInfo);
		}
	}

	public void clearSortInfoList()
	{
		this.sortInfoList.clear();
	}

	public boolean containsSortInfo(String key)
	{
		return this.sortInfoList.containsKey(key);
	}


	public SortInfo createSortInfo()
	{
		SortInfo sortInfo = new SortInfo();

		sortInfo.setSortingId(this.createSortingId());
		long currentTime = System.currentTimeMillis();
		sortInfo.setCurrentTime(currentTime);
		return sortInfo;
	}

	public SortInfo getSortInfo(String key)
	{
		return this.sortInfoList.get(key.toLowerCase());
	}

	public int getSortInfoCount()
	{
		return this.sortInfoList.size();
	}

	public SortInfo[] getSortInfoList()
	{
		return this.sortInfoList.values().toArray(new SortInfo[0]);
	}

	public void handleSortInfoResult(SortInfo sortInfo)
	{
		int errorCode = sortInfo.getErrorCodeSVR();

		if (errorCode != 0)
		{
			sortInfo.getSlotsList().clear();
			List<Integer> slots = SlotManager.getInstance().getTrashSlots(errorCode);
			if (slots != null)
			{
				sortInfo.getSlotsList().addAll(slots);
			}
		}
	}

	public SortInfo removeSortInfo(String key)
	{
		return this.sortInfoList.remove(key);
	}

	private String createSortingId()
	{
		UUID uuid = UUID.randomUUID();
		long now = System.currentTimeMillis();
		String timeInfo = String.valueOf(now);
		return uuid.toString() + "-" + timeInfo;
	}

	public void handlerOverTimePacketOnInfo()
	{
		long currentTime = System.currentTimeMillis();

		for (SortInfo info : this.sortInfoList.values())
		{
			long packetOnTime = info.getCurrentTime();

			long spanTime = currentTime - packetOnTime;
			if (spanTime > 60 * 1000 * 20)
			{
				String plcKey = info.getPlcId();

				try {
					if (info.getErrorCodeSVR()==0){
						info.setErrorCodePLC(SortCommonDefines.ERROR_CODE_6_LOST_PACKET);
						List<Integer> slots = SlotManager.getInstance().getTrashSlots(SortCommonDefines.ERROR_CODE_6_LOST_PACKET);
						info.setDroppedSlotId(slots.isEmpty()?0:slots.get(0));
					}else {
						info.setErrorCodePLC(info.getErrorCodeSVR());
						List<Integer> slots = info.getSlotsList();
						info.setDroppedSlotId(slots.isEmpty()?0:slots.get(0));
					}

					Timestamp droppedTime = SortProtocolCreator.getInstance().createCurrentTimeStamp();
					info.setTimestampPacketOff(droppedTime);
					info.setTimePacketOff(droppedTime.toString());

					SortControllerManager.getInstance().onPacketOffMessage(info);

				}catch (Exception e){
					LogUtil.LogError(logger, "[WheelSortInfoManager.handlerOverTimePacketOnInfo] Auto remove SortInfo Error: PLC ID:" + plcKey+", Msg:"+e.getMessage());
				}finally {
					SortInfoManager.getInstance().removeSortInfo(plcKey);
					LogUtil.LogError(logger, "[WheelSortInfoManager.handlerOverTimePacketOnInfo] Auto remove SortInfo. PLC ID:" + plcKey);
				}
			}
		}

	}
}
